<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Section 10.6.&nbsp; Reentrant Functions</title>
<link rel="STYLESHEET" type="text/css" href="images/style.css">
<link rel="STYLESHEET" type="text/css" href="images/docsafari.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch10lev1sec5.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch10lev1sec7.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
<br><table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td valign="top"><a name="ch10lev1sec6"></a>
<h3 class="docSection1Title">10.6. Reentrant Functions</h3>
<p class="docText">When a signal that is being caught is handled by a process, the normal sequence of instructions being executed by the process is temporarily interrupted by the signal handler. The process then continues executing, but the instructions in the signal handler are now executed. If the signal handler returns (instead of calling <tt>exit</tt> or <tt>longjmp</tt>, for example), then the normal sequence of instructions that the process was executing when the signal was caught continues executing. (This is similar to what happens when a hardware interrupt occurs.) But in the signal handler, we can't tell where the process was executing when the signal was caught. What if the process was in the middle of allocating additional memory on its heap using <tt>malloc</tt>, and we call <a name="idd1e71626"></a><a name="idd1e71631"></a><a name="idd1e71636"></a><a name="idd1e71641"></a><a name="idd1e71646"></a><a name="idd1e71651"></a><a name="idd1e71656"></a><a name="idd1e71661"></a><a name="idd1e71666"></a><a name="idd1e71671"></a><a name="idd1e71676"></a><a name="idd1e71681"></a><a name="idd1e71686"></a><a name="idd1e71691"></a><a name="idd1e71696"></a><a name="idd1e71701"></a><a name="idd1e71706"></a><a name="idd1e71711"></a><a name="idd1e71716"></a><a name="idd1e71721"></a><a name="idd1e71726"></a><a name="idd1e71731"></a><a name="idd1e71736"></a><a name="idd1e71741"></a><a name="idd1e71746"></a><a name="idd1e71751"></a><a name="idd1e71756"></a><a name="idd1e71761"></a><a name="idd1e71766"></a><a name="idd1e71771"></a><a name="idd1e71776"></a><a name="idd1e71781"></a><a name="idd1e71786"></a><a name="idd1e71791"></a><a name="idd1e71796"></a><a name="idd1e71801"></a><a name="idd1e71806"></a><a name="idd1e71811"></a><a name="idd1e71816"></a><a name="idd1e71821"></a><a name="idd1e71826"></a><a name="idd1e71831"></a><a name="idd1e71836"></a><a name="idd1e71841"></a><a name="idd1e71846"></a><a name="idd1e71851"></a><a name="idd1e71856"></a><a name="idd1e71861"></a><a name="idd1e71866"></a><a name="idd1e71871"></a><a name="idd1e71876"></a><a name="idd1e71881"></a><a name="idd1e71886"></a><a name="idd1e71891"></a><a name="idd1e71896"></a><a name="idd1e71901"></a><a name="idd1e71906"></a><a name="idd1e71911"></a><a name="idd1e71916"></a><a name="idd1e71921"></a><a name="idd1e71926"></a><a name="idd1e71931"></a><a name="idd1e71936"></a><a name="idd1e71941"></a><a name="idd1e71946"></a><a name="idd1e71951"></a><a name="idd1e71956"></a><a name="idd1e71961"></a><a name="idd1e71966"></a><a name="idd1e71971"></a><a name="idd1e71976"></a><a name="idd1e71981"></a><a name="idd1e71986"></a><a name="idd1e71991"></a><a name="idd1e71996"></a><a name="idd1e72001"></a><a name="idd1e72006"></a><a name="idd1e72011"></a><a name="idd1e72016"></a><a name="idd1e72021"></a><a name="idd1e72026"></a><a name="idd1e72031"></a><a name="idd1e72036"></a><a name="idd1e72041"></a><a name="idd1e72046"></a><a name="idd1e72051"></a><a name="idd1e72056"></a><a name="idd1e72061"></a><a name="idd1e72066"></a><a name="idd1e72071"></a><a name="idd1e72076"></a><a name="idd1e72081"></a><a name="idd1e72086"></a><a name="idd1e72091"></a><a name="idd1e72096"></a><a name="idd1e72099"></a><a name="idd1e72104"></a><a name="idd1e72109"></a><a name="idd1e72114"></a><a name="idd1e72119"></a><a name="idd1e72124"></a><a name="idd1e72129"></a><a name="idd1e72134"></a><a name="idd1e72139"></a><a name="idd1e72144"></a><a name="idd1e72149"></a><a name="idd1e72154"></a><a name="idd1e72159"></a><a name="idd1e72164"></a><a name="idd1e72169"></a><a name="idd1e72174"></a><a name="idd1e72179"></a><a name="idd1e72184"></a><a name="idd1e72189"></a><a name="idd1e72194"></a><a name="idd1e72199"></a><a name="idd1e72204"></a><tt>malloc</tt> from the signal handler? Or, what if the process was in the middle of a call to a function, such as <tt>getpwnam</tt> (<a class="docLink" href="ch06lev1sec2.html#ch06lev1sec2">Section 6.2</a>), that stores its result in a static location, and we call the same function from the signal handler? In the <tt>malloc</tt> example, havoc can result for the process, since <tt>malloc</tt> usually maintains a linked list of all its allocated areas, and it may have been in the middle of changing this list. In the case of <tt>getpwnam</tt>, the information returned to the normal caller can get overwritten with the information returned to the signal handler.</P>
<p class="docText">The Single UNIX Specification specifies the functions that are guaranteed to be reentrant. <a class="docLink" href="#ch10fig04">Figure 10.4</a> lists these reentrant functions.</P>
<a name="ch10fig04"></a><p><table cellspacing="0" class="allBorders" border="1" RULES="cols" cellpadding="5"><caption><H5 class="docTableTitle">Figure 10.4. Reentrant functions that may be called from a signal handler</H5></caption><colgroup><col width="100"><col width="100"><col width="100"><col width="100"><col width="100"></colgroup><thead></thead><TR><td class="docTableCell" align="left" valign="top"><p class="docText">
<tt>accept</tt></P></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>fchmod</tt></p></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>lseek</tt></P></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>sendto</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>stat</tt>
</p></TD></TR><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>access</tt></p></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>fchown</tt></p></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>lstat</tt></P></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>setgid</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>symlink</tt>
</p></td></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>aio_error</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>fcntl</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>mkdir</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>setpgid</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>sysconf</tt>
</P></td></TR><TR><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>aio_return</tt></p></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>fdatasync</tt></P></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>mkfifo</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>setsid</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>tcdrain</tt>
</p></td></tr><tr><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>aio_suspend</tt></p></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>fork</tt></P></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>open</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>setsockopt</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>tcflow</tt>
</p></td></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>alarm</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>fpathconf</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>pathconf</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>setuid</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>tcflush</tt>
</P></TD></tr><TR><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>bind</tt></P></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>fstat</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>pause</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>shutdown</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>tcgetattr</tt>
</p></TD></tr><TR><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>cfgetispeed</tt></P></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>fsync</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>pipe</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>sigaction</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>tcgetpgrp</tt>
</p></td></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>cfgetospeed</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>ftruncate</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>poll</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>sigaddset</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>tcsendbreak</tt>
</P></td></TR><TR><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>cfsetispeed</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>getegid</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>posix_trace_event</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>sigdelset</tt></p></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>tcsetattr</tt>
</P></td></TR><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>cfsetospeed</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>geteuid</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>pselect</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>sigemptyset</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>tcsetpgrp</tt>
</p></td></tr><TR><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>chdir</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>getgid</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>raise</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>sigfillset</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>time</tt>
</P></TD></tr><TR><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>chmod</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>getgroups</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>read</tt></p></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>sigismember</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>timer_getoverrun</tt>
</p></td></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>chown</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>getpeername</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>readlink</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>signal</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>timer_gettime</tt>
</P></TD></tr><TR><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>clock_gettime</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>getpgrp</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>recv</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>sigpause</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>timer_settime</tt>
</P></TD></tr><TR><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>close</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>getpid</tt></p></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>recvfrom</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>sigpending</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>times</tt>
</p></td></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>connect</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>getppid</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>recvmsg</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>sigprocmask</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>umask</tt>
</P></TD></TR><tr><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>creat</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>getsockname</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>rename</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>sigqueue</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>uname</tt>
</P></TD></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>dup</tt></p></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>getsockopt</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>rmdir</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>sigset</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>unlink</tt>
</p></td></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>dup2</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>getuid</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>select</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>sigsuspend</tt></P></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>utime</tt>
</p></TD></TR><TR><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>execle</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>kill</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>sem_post</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>sleep</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>wait</tt>
</p></td></tr><TR><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>execve</tt></P></td><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>link</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>send</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>socket</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>waitpid</tt>
</p></td></tr><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>_Exit &amp; _exit</tt></p></td><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>listen</tt></P></TD><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>sendmsg</tt></P></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>socketpair</tt></p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText"><tt>write</tt>
</P></td></TR></table></p><BR>
<p class="docText">Most functions that are not in <a class="docLink" href="#ch10fig04">Figure 10.4</a> are missing because (a) they are known to use static data structures, (b) they call <tt>malloc</tt> or <tt>free</tt>, or (c) they are part of the standard I/O library. Most implementations of the standard I/O library use global data structures in a nonreentrant way. Note that even though we call <tt>printf</tt> from signal handlers in some of our examples, it is not guaranteed to produce the expected results, since the signal hander can interrupt a call to <tt>printf</tt> from our main program.</P>
<p class="docText">Be aware that even if we call a function listed in <a class="docLink" href="#ch10fig04">Figure 10.4</a> from a signal handler, there is only one <tt>errno</tt> variable per thread (recall the discussion of <tt>errno</tt> and threads in <a class="docLink" href="ch01lev1sec7.html#ch01lev1sec7">Section 1.7</a>), and we might modify its value. Consider a signal handler that is invoked right after <tt>main</tt> has set <tt>errno</tt>. If the signal handler calls <tt>read</tt>, for example, this call can change the value of <tt>errno</tt>, wiping out the value that was just stored in <tt>main</tt>. Therefore, as a general rule, when calling the functions listed in <a class="docLink" href="#ch10fig04">Figure 10.4</a> from a signal handler, we should save and restore <tt>errno</tt>. (Be aware that a commonly caught <a name="idd1e72986"></a><a name="idd1e72991"></a><a name="idd1e72996"></a><a name="idd1e73001"></a><a name="idd1e73006"></a><a name="idd1e73011"></a><a name="idd1e73016"></a><a name="idd1e73021"></a>signal is <tt>SIGCHLD</tt>, and its signal handler usually calls one of the <tt>wait</tt> functions. All the <tt>wait</tt> functions can change <tt>errno</tt>.)</P>
<p class="docText">Note that <tt>longjmp</tt> (<a class="docLink" href="ch07lev1sec10.html#ch07lev1sec10">Section 7.10</a>) and <tt>siglongjmp</tt> (<a class="docLink" href="ch10lev1sec15.html#ch10lev1sec15">Section 10.15</a>) are missing from <a class="docLink" href="#ch10fig04">Figure 10.4</a>, because the signal may have occurred while the main routine was updating a data structure in a nonreentrant way. This data structure could be left half updated if we call <tt>siglongjmp</tt> instead of returning from the signal handler. If it is going to do such things as update global data structures, as we describe here, while catching signals that cause <tt>sigsetjmp</tt> to be executed, an application needs to block the signals while updating the data structures.</p>
<a name="ch10ex02"></a>
<H5 class="docExampleTitle">Example</H5>
<p class="docText"><a class="docLink" href="#ch10fig05">Figure 10.5</a> shows a program that calls the nonreentrant function <tt>getpwnam</tt> from a signal handler that is called every second. We describe the <tt>alarm</tt> function in <a class="docLink" href="ch10lev1sec10.html#ch10lev1sec10">Section 10.10</a>. We use it here to generate a <tt>SIGALRM</tt> signal every second.</p>
<p class="docText">When this program was run, the results were random. Usually, the program would be terminated by a <tt>SIGSEGV</tt> signal when the signal handler returned after several iterations. An examination of the <tt>core</tt> file showed that the <tt>main</tt> function had called <a name="idd1e73102"></a><a name="idd1e73107"></a><a name="idd1e73110"></a><a name="idd1e73113"></a><a name="idd1e73116"></a><a name="idd1e73121"></a><a name="idd1e73126"></a><a name="idd1e73131"></a><a name="idd1e73138"></a><a name="idd1e73143"></a><a name="idd1e73148"></a><a name="idd1e73153"></a><a name="idd1e73158"></a><a name="idd1e73161"></a><a name="idd1e73164"></a><a name="idd1e73167"></a><tt>getpwnam</tt>, but that some internal pointers had been corrupted when the signal handler called the same function. Occasionally, the program would run for several seconds before crashing with a <tt>SIGSEGV</tt> error. When the <tt>main</tt> function did run correctly after the signal had been caught, the return value was sometimes corrupted and sometimes fine. Once (on Mac OS X), messages were printed from the <tt>malloc</tt> library routine warning about freeing pointers not allocated through <tt>malloc</tt>.</P>
<p class="docText">As shown by this example, if we call a nonreentrant function from a signal handler, the results are unpredictable.</P>

<a name="ch10fig05"></a>
<h5 class="docExampleTitle">Figure 10.5. Call a nonreentrant function from a signal handler</h5>

<pre>#include "apue.h"
#include &lt;pwd.h&gt;

static void
my_alarm(int signo)
{
    struct passwd   *rootptr;

    printf("in signal handler\n");
    if ((rootptr = getpwnam("root")) == NULL)
            err_sys("getpwnam(root) error");
    alarm(1);
}

int
main(void)
{
    struct passwd   *ptr;

    signal(SIGALRM, my_alarm);
    alarm(1);
    for ( ; ; ) {
        if ((ptr = getpwnam("sar")) == NULL)
            err_sys("getpwnam error");
        if (strcmp(ptr-&gt;pw_name, "sar") != 0)
            printf("return value corrupted!, pw_name = %s\n",
                    ptr-&gt;pw_name);
    }
}
</pre><br>



<a href="17021535.html"><img src="images/pixel.gif" alt="" width="1" height="1" border="0"></a><ul></UL></td></TR></table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch10lev1sec5.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch10lev1sec7.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
</body></html><br>
<table width="100%" cellspacing="0" cellpadding="0"
style="margin-top: 0pt; border-collapse: collapse;"> 
<tr> <td align="right" style="background-color=white; border-top: 1px solid gray;"> 
<a href="http://www.zipghost.com/" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">The CHM file was converted to HTM by Trial version of <b>ChmD<!--29-->ecompiler</b>.</a>
</TD>
</TR><tr>
<td align="right" style="background-color=white; "> 
<a href="http://www.etextwizard.com/download/cd/cdsetup.exe" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">Download <b>ChmDec<!--29-->ompiler</b> at: http://www.zipghost.com</a>
</TD></tr></table>
